package cn.chinaunicom.admin.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zz.gmhelper.SM2Util;
import org.zz.gmhelper.cert.SM2CertUtil;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.easy.secret.config.SecureProperties;
import com.easy.secret.utils.RandomFileUtil;

import cn.chinaunicom.admin.entity.AppServer;
import cn.chinaunicom.admin.entity.DigitalEnvelope;
import cn.chinaunicom.admin.service.IDigitalEnvelopService;
import cn.chinaunicom.admin.utils.AppContextHandler;
import cn.chinaunicom.fast.common.constant.Constants;
import cn.chinaunicom.fast.common.constant.RedisKeys;
import cn.chinaunicom.fast.common.exception.AuthErrorType;
import cn.chinaunicom.fast.common.exception.BaseException;
import cn.chinaunicom.fast.common.utils.MyCache;
import lombok.extern.slf4j.Slf4j;

/**
 * @ProjectName: esay-secret-server
 * @Package: cn.chinaunicom.admin.service.impl
 * @ClassName: DigitalEnvelopServiceImpl
 * @Description: 数字信封业务处理类
 * @Author: wangjc
 * @CreateDate: 2023/11/22
 * @UpdateUser: wangjc
 * @UpdateDate: 2023/11/22
 * @UpdateRemark: 更新内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class DigitalEnvelopServiceImpl implements IDigitalEnvelopService {

    @Autowired
    private SecureProperties properties;

    @Autowired
    private MyCache cache;

    @Override
    public DigitalEnvelope add(DigitalEnvelope de) {
        de.setDeId(IdWorker.get32UUID());
        de.setCdate(new Date());
        de.setCuser(Constants.SYSADMIN_USER);
        de.setBatchNo(IdWorker.get32UUID());
        de.setSts(Constants.STR_YES_ONE);

        // 保存缓存
        cache.setCache(RedisKeys.DIGITAL_ENVELOPE_INFO + de.getDeId(), de);

        // 数据保存
        List<DigitalEnvelope> list = getList();
        list.add(de);
        cache.setCache(RedisKeys.DIGITAL_ENVELOPE_LIST, list);
        return de;
    }

    private List<DigitalEnvelope> getList() {
        List<DigitalEnvelope> list = (List<DigitalEnvelope>) this.cache.getCache(RedisKeys.DIGITAL_ENVELOPE_LIST);
        return (list == null) ? new ArrayList<DigitalEnvelope>() : list;
    }

    @Override
    public void del(String deId) {
        DigitalEnvelope de = (DigitalEnvelope) this.cache.getCache(RedisKeys.DIGITAL_ENVELOPE_INFO + deId);
        de.setSts(Constants.STR_NO_ZERO);
        de.setUdate(new Date());
        de.setUuser(Constants.SYSADMIN_USER);
        // 保存缓存
        cache.setCache(RedisKeys.DIGITAL_ENVELOPE_INFO + de.getDeId(), de);

        // 数据保存
        List<DigitalEnvelope> list = getList();
        list.parallelStream().filter(d -> d.getDeId().equals(deId)).forEach(d -> d = de);
        cache.setCache(RedisKeys.DIGITAL_ENVELOPE_LIST, list);
    }

    @Override
    public DigitalEnvelope upd(DigitalEnvelope de) {
        DigitalEnvelope deCache = (DigitalEnvelope) this.cache.getCache(RedisKeys.DIGITAL_ENVELOPE_INFO + de.getDeId());
        BeanUtils.copyProperties(de, deCache);
        deCache.setUdate(new Date());
        deCache.setUuser(Constants.SYSADMIN_USER);
        // 保存缓存
        cache.setCache(RedisKeys.DIGITAL_ENVELOPE_INFO + de.getDeId(), deCache);

        // 数据保存
        List<DigitalEnvelope> list = getList();
        list.parallelStream().filter(d -> d.getDeId().equals(de.getDeId())).forEach(d -> d = de);
        cache.setCache(RedisKeys.DIGITAL_ENVELOPE_LIST, list);
        return deCache;
    }

    @Override
    public List<DigitalEnvelope> listAll() {
        return getList();
    }

    @Override
    public DigitalEnvelope get(String deId) {
        return (DigitalEnvelope) this.cache.getCache(RedisKeys.DIGITAL_ENVELOPE_INFO + deId);
    }

    @Override
    public String getKeyToHexString(String deId) {
        AppServer app = AppContextHandler.getInstance().getApp();
        if(Objects.isNull(app)){
            throw new BaseException(AuthErrorType.INVALID_REQUEST);
        }
        DigitalEnvelope de = this.get(deId);
        if(Objects.isNull(de)) {
            log.error("没有当前id:[{}]得数字信封数据", deId);
            return null;
        }
        // 此应用不能访问此分仓id
        if(!de.getCompartId().equals(app.getAppId())) {
            throw new BaseException(AuthErrorType.INSUFFICIENT_SCOPE);
        }
        try{
            byte[] key = ByteUtils.fromHexString(de.getPriKey());
            byte[] pubKey = RandomFileUtil.readFile(properties.getPfxFileName());
            BCECPublicKey publicKeyFromPfx = SM2CertUtil.getPublicKeyFromPfx(pubKey, properties.getPfxPasswd());
            byte[] encrypt = SM2Util.encrypt(publicKeyFromPfx, key);
            return ByteUtils.toHexString(encrypt);
        } catch (Exception e) {
            log.error("加密数字信封中的key失败：{}", e);
        }
        return null;
    }
}
